// API:
//
// Open(initialDeposit int64) *Account
// (Account) Close() (payout int64, ok bool)
// (Account) Balance() (balance int64, ok bool)
// (Account) Deposit(amount int64) (newBalance int64, ok bool)
//
// If Open is given a negative initial deposit, it must return nil.
// Deposit must handle a negative amount as a withdrawal.
// If any Account method is called on an closed account, it must not modify
// the account and must return ok = false.

package account

import (
	"sync"
)

const testVersion = 1

type Account struct {
	amt   int64
	close bool
	mux   sync.Mutex
}

func Open(initialDeposit int64) (a *Account) {
	if initialDeposit < 0 {
		a = nil
		return
	}

	a = &Account{
		amt: initialDeposit,
	}

	return
}

func (a *Account) Close() (payout int64, ok bool) {
	if a.close {
		return
	}

	a.mux.Lock()
	if !a.close {
		a.close = true

		ok = true
		payout = a.amt
	}
	a.mux.Unlock()

	return
}

func (a *Account) Balance() (balance int64, ok bool) {
	if a.close {
		return
	}

	ok = true
	balance = a.amt

	return
}

func (a *Account) Deposit(amount int64) (newBalance int64, ok bool) {
	if a.close {
		return
	}

	a.mux.Lock()
	defer a.mux.Unlock()
	if a.amt+amount < 0 {
		// a.mux.Unlock()
		return
	}

	a.amt = a.amt + amount
	// a.mux.Unlock()

	ok = true
	newBalance = a.amt

	return
}
